;*******************************************************************************
;   Portation of G2xxx BSL is a Boot Strap Loader for MSP430G2xx3 with
;   small Flash Footprint so that it fits into info memory ( <256 Bytes)
;
;                MSP430G2xx3
;             -----------------
;         /|\|                 |
;          | |        P1.0/P1.6|---> LED
;          --|RST              |
;            |                 |
;            |      BSLPIN/P1.3|<--- Enable Pin / S2 on LaunchPad
;            |                 |
;            |                 |
;            |          rX/P1.1|<--- UART 9600 8N1
;            |          tX/P1.2|---> rx/tx swapped on LaunchPad!
;             -----------------
;
;
;   Texas Instruments
;
;*******************************************************************************
;  Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com/
;
;  Redistribution and use in source and binary forms, with or without
;  modification, are permitted provided that the following conditions
;  are met:
;
;    Redistributions of source code must retain the above copyright
;    notice, this list of conditions and the following disclaimer.
;
;    Redistributions in binary form must reproduce the above copyright
;    notice, this list of conditions and the following disclaimer in the
;    documentation and/or other materials provided with the
;    distribution.
;
;    Neither the name of Texas Instruments Incorporated nor the names of
;    its contributors may be used to endorse or promote products derived
;    from this software without specific prior written permission.
;
;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
;  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
;  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
;  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
;  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
;  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
;  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;

;*******************************************************************************
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            ;Main / Customer Application
;-------------------------------------------------------------------------------
LED         .equ    BIT0                    ; RED LED
;LED        .equ    BIT6                    ; GREEN LED
;-------------------------------------------------------------------------------
            .text                           ; User Application
            ; ================================================================
            ; Never place any code / data between .text (RSEG CODE) and main
            ; label. This adress is used as start adress for user code
            ; ================================================================
;-------------------------------------------------------------------------------
            ; Customer Application starts here
main        mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop Watchdog Timer

Mainloop    jmp     Mainloop                ; Again
;-------------------------------------------------------------------------------
            ;END of Main / Customer Application
;-------------------------------------------------------------------------------



;-------------------------------------------------------------------------------
            .sect   ".bsl"        ;BSL Application
;-------------------------------------------------------------------------------

;           Flash Main Segment Start Adress (see datasheet)
FLASHSTART  .equ    main                    ; Lowest main flash address

;           CPU registers used for BSL
txData      .equ    R5
rxData      .equ    R6
rCHKSUM     .equ    R7
rPoint      .equ    R8
rTemp       .equ    R9

RXD         .equ    BIT1                    ; RXD on P1.1
TXD         .equ    BIT2                    ; TXD on P1.2
BSLPIN      .equ    BIT3                    ; BSL entry on P1.3 LOW (Use pullup)

;           Command number definition
CMD_SYNC    .equ    0BAh
ACK    		.equ    0F8h
NACK    	.equ    0FEh

;-------------------------------------------------------------------------------
;           Start of BSL Code
;-------------------------------------------------------------------------------
;BeginOfInfo jmp     $                       ; Safety: Avoid code run through

RESET
            bit.b   #BSLPIN,&P1IN           ; Pin low invokes BSL
BslEntry?   jz      InvokeBsl
            br      #main                   ; Exit BSL if pin not set

;-------------------------------------------------------------------------------
;           BSL Invoked
;-------------------------------------------------------------------------------
InvokeBsl   mov.w   #280h,SP                ; Init Stackpointer to top of RAM
                                            ; RAM: 0x27f - 0x200

StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop Watchdog Timer

SetupDCO    ; Set DCO to calibrated 1 MHz:
            ;clr.b   &DCOCTL                 ; Lowest DCOx and MODx settings
            mov.b   &CALDCO_1MHZ,&DCOCTL    ; Copy from address 0x010FEh
            mov.b   &CALBC1_1MHZ,&BCSCTL1   ; Copy from address 0x010FFh

;OutputSMCLK bis.b   #BIT4,&P1DIR           ; Output SMCLK to check Frequency
;            bis.b   #BIT4,&P1SEL

SetupPins   bis.b   #(RXD+TXD),&P1SEL         ; setup USCI Rx/Tx pins
			bis.b	#(RXD+TXD),&P1SEL2

SetupUSCI	mov.b	#(UCSWRST+UCSSEL_2),&UCA0CTL1  ; USCI reset, clk source SMCLK
			mov.b 	#(104),&UCA0BR0
			mov.b 	#(0),&UCA0BR1
			mov.b 	#(UCBRS_1),&UCA0MCTL
			bic.b 	#(UCSWRST),&UCA0CTL1

;-------------------------------------------------------------------------------
MainBsl             ; BSL Main Loop
;-------------------------------------------------------------------------------
Wait4sync   call    #RxOneByte

SyncCmd?    cmp     #CMD_SYNC,rxData        ; Sync command received?
            jne     BSLEnd                  ; Exit BSL if no Sync Byte

;-------------------------------------------------------------------------------
CmdFct_Erase        ; Erase main flash and restore interrupt vectors
;-------------------------------------------------------------------------------
            ; erase from bottom up
            mov.w   #FLASHSTART, rPoint     ; FLASH start address
EraseSeg    mov     &(FWKEY+ERASE),&FCTL1     ; ERASE=1. Erase Segment
            mov     &(FWKEY+FSSEL_2 + 2), &FCTL2
UnlockFlash ;mov.w   #FWKEY+00h,&FCTL3       ; LOCK=0, all others 0
			mov.w   #FWKEY+LOCKA,&FCTL3       ; LOCK=0, LOCKA = 1, all others 0

            ; Start praying here that nothing happens during next CPU cycles
            mov.b   #0h,0(rPoint)           ; Start erase with dummy write
            cmp.w   #0FE00h, rPoint         ; Interrupt vector segment just erased?
            jge     WrtRstVec               ; Restore it!
            add.w   #512,rPoint             ; Next segment (add segment size)
            jmp     EraseSeg                ; Repeat segment erase

WrtRstVec   mov     #FWKEY+WRT,&FCTL1       ; WRT=1. Write to segment
            mov     #RESET,&0FFFEh          ; Point reset vector to BSL
            ; You can stop praying here. Everything went fine once PC is here

            ; ================================================================
            ; Erasing Flash and rewriting vectors take approx 16 ms
            ;  Make sure to wait this time before new data is sent to MSP430
            ;  The UART function is placed in flash thus preventing access
            ;  to it while flash erase / write.
            ; ================================================================

;-------------------------------------------------------------------------------
CmdFct_Write        ; Write 512 - 2 Byte to Main memory
;-------------------------------------------------------------------------------
            ;mov    #FWKEY+WRT,&FCTL1       ; Writing is still enabled
            ; Keeping WRT enabled w/o writing does not account into write time

            mov     #FLASHSTART,rPoint      ; Point to first position in FLASH
            clr     rCHKSUM                 ; Init Checksum

            ; ================================================================
            ; Ensure a minimum delay of 16 ms between SYNC and first byte
            ; ================================================================

CFW_w4d     call    #RxOneByte

CFW_Range   cmp     #0FFFEh, rPoint         ; Pointer to Reset Vector?
            jeq     CFW_Done                ; Skip and exit Write
            mov.b   rxData,0(rPoint)        ; Write 8 bit data to flash

CFW_COMM
CFW_Xor     xor.b   @rPoint+,rCHKSUM        ; xor checksum and inc pointer
            ;inc    rPoint                  ; inc done above w/ Auto increment
            jmp     CFW_w4d                 ; wait for next byte

CFW_Done    ; ================================================================
            ; rx'ed byte for adress 0xffe (RESET) contains checksum
            ; ================================================================
            cmp.b   rxData, rCHKSUM         ; XOR'ing calc checksum with sent
            jeq     LoadAck                 ;  should result in ZERO if match

            ; send NACK
            mov.w   #NACK, &UCA0TXBUF 		; Copy byte
			jmp		SendAckNack

			; send ACK
LoadAck		mov.w   #ACK, &UCA0TXBUF 		; Copy byte

SendAckNack

WaitTxBusy	bit.b 	#UCBUSY, &UCA0STAT
			jnz 	WaitTxBusy

            ; ================================================================
            ; Reset sequence required to exit BSL
            ; Do not jmp to main here - system is not in its initial state!
            ; ================================================================
BSLEnd      ;jmp     MainBsl                ; Start BSL over again
            clr     WDTCTL                  ; Exit BSL by issuing RESET
            ; ================================================================
            ; Reset sequence required to exit BSL
            ; Do not jmp to main here - system is not in its initial state!
            ; ================================================================

;-------------------------------------------------------------------------------
RxOneByte   ; USCI on byte receive function
;-------------------------------------------------------------------------------
WaitRxIFG  	bit.b   #UCA0RXIFG, &IFG2       ; Test UCA0RXIFG Bit
            jz      WaitRxIFG

            mov.b   &UCA0RXBUF,rxData       ; Copy received byte
RxDone      ret


;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------

            .sect   ".reset"                ; RESET Vector
            .short  RESET                   ; POR, ext. Reset

            .end
